package com.jsecode.protocol.gid22.entity;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Gid22WarnFlag {
    private static final Logger logger = LoggerFactory.getLogger(Gid22WarnFlag.class);
    public byte warn1;     //    BIT0  碰撞报警
                            //    BIT1  拖车报警
                            //    BIT2  翻车报警
                            //    BIT3  低电压报警（汽车）
                            //    BIT4  碰撞测试报警
                            //          新增加速度超过1G小于4G上报，
                            //          用以监控车辆加速度情况。
    public byte warn2; 
                            //    BIT0  汽车点火上报
                            //    BIT1  汽车熄火上报
                            //    BIT2  车机拔出报警(带电池情况下)
                            //    BIT3  车机插上报警(带电池情况下)
                            //    BIT4  定位过长报警
                            //    BIT5  怠速过长上报
    public byte warn3; 
                            //    BIT0  GID FLASH故障报警
                            //    BIT1  GID CAN模块故障报警
                            //    BIT2  GID 3D传感器故障报警
                            //    BIT3  GID GPS模块故障报警
    
    public boolean bCrashAcceleration = true;  // 碰撞报警, 要计算一个加速度, 如果不符合则设置为false.

    public Gid22WarnFlag() {}
    
    public Gid22WarnFlag(byte warn1, byte warn2, byte warn3) {
        this.warn1 = warn1;
        this.warn2 = warn2;
        this.warn3 = warn3;
    }

    public boolean isCrash() {
        return (isBitOne(warn1, 0) || isBitOne(warn1,4)) && bCrashAcceleration;
    }
    
    public boolean isTrailCar() {
        return isBitOne(warn1, 1);
    }
    
    public boolean isTureOverCar() {
        return isBitOne(warn1, 2);
    }

    public boolean isPowerLower() {
        return isBitOne(warn1, 3);
    }

    // 第2个字节
    public boolean isPowerLost() {
        return isBitOne(warn2, 2);
    }
    
    public boolean isPositioningLong() { //定位过长报警
        return isBitOne(warn2, 4);
    }
    public boolean isIdleLong() { 
        return isBitOne(warn2, 5);
    }
    
    // 第3个字节
    public boolean isFailFlash() {
        return isBitOne(warn3, 0);
    }
    public boolean isFailCan() {
        return isBitOne(warn3, 1);
    }
    public boolean isFail3D() {
        return isBitOne(warn3, 2);
    }
    public boolean isFailGps() {
        return isBitOne(warn3, 3);
    }
    
    /**
     * @param uByte 
     * @param bitIndex 表示bit0, bit1,...
     *
     */
    private static boolean isBitOne(byte uByte, int bitIndex) {
        return ((uByte&(0x1<<bitIndex))>0);
    }

    /**
     * 解析报警信息
     * @param attachData 后续可能是6个字节， 也可能是2个字节
     * 
     */
    public Gid22WarnFlag parseWarnType(byte[] attachData) {
        int accelerationX = 0; // 精度0.1G
        int accelerationY = 0; // 精度0.1G
        int accelerationZ = 0; // 精度0.1G

        Gid22WarnFlag warnPack = this;
        // 数据长度最后有XOR和0xFB
        int curIndex = 0;
        // 如果是碰撞报警, 检查加速度
        if (warnPack.isCrash() && attachData != null && attachData.length >= 6) {
            // x,y,z, 各占2个字节
            accelerationX = ((attachData[curIndex]&0x7F)<<8) | (attachData[curIndex+1]&0xFF);
            if ((attachData[curIndex]&0x80)==0x80) {
                accelerationX = -accelerationX;
            }                
            curIndex = curIndex + 2;

            accelerationY = ((attachData[curIndex]&0x7F)<<8) | (attachData[curIndex+1]&0xFF);
            if ((attachData[curIndex]&0x80)==0x80) {
                accelerationY = -accelerationY;
            }
            curIndex = curIndex + 2;

            accelerationZ = ((attachData[curIndex]&0x7F)<<8) | (attachData[curIndex+1]&0xFF);
            if ((attachData[curIndex]&0x80)==0x80) {
                accelerationZ = -accelerationZ;
            }
            curIndex = curIndex + 2;
            logger.info("x is " + accelerationX + " y is " + accelerationY + " z is " + accelerationZ);

            float maxAcceleration = (float) Math.sqrt(accelerationX*accelerationX+accelerationY*accelerationY+accelerationZ*accelerationZ);
            //  float maxAcceleration = (float)(maxValue * 0.1);
            //if acceleration is less than 4, cancel the impact alert
            if( maxAcceleration<39f || maxAcceleration>160f) {
                warnPack.bCrashAcceleration = false;
                logger.info("cancel impact alert !");
            }
        }
        // TODO: 2 个字节为怠速报警， 暂时不做处理
        return warnPack;
    }
    
    public static void main(String[] argv) {
        System.out.println(isBitOne((byte)0x08,7));
    }
}
